package com.cy.pj.sys.service;

import com.cy.pj.common.exception.ServiceException;
import com.cy.pj.common.vo.CheckBox;
import com.cy.pj.common.vo.PageObject;
import com.cy.pj.sys.entity.SysRole;
import com.cy.pj.sys.entity.SysUser;
import com.cy.pj.sys.mapper.SysRoleMapper;
import com.cy.pj.sys.mapper.SysRoleMenuMapper;
import com.cy.pj.sys.mapper.SysUserRoleMapper;
import com.cy.pj.sys.vo.SysRoleMenuVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
public class SysRoleServiceImpl implements SysRoleService {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysRoleMapper sysRoleMapper;//角色mapper

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;//角色菜单mapper

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper; //用户角色mapper

    @Override
    public PageObject<SysRole> findPageObjects(String name,
                                               Integer pageCurrent) {
        //1.对参数进行校验
        if (pageCurrent == null || pageCurrent < 1)
            throw new IllegalArgumentException("当前页码值无效");
        //2.查询记录总数并进行校验
        int rowCount = sysRoleMapper.getRowCount(name);
        if (rowCount == 0)
            throw new ServiceException("没有找到对应的记录");
        //3.查询当前页记录
        int pageSize = 5;
        int startIndex = (pageCurrent - 1) * pageSize;
        List<SysRole> records =
                sysRoleMapper.findPageObjects(name, startIndex, pageSize);
        //4.对查询结果封装并返回
        return new PageObject<>(pageCurrent, pageSize, rowCount, records);
    }

    /**
     * 基于角色id:
     * 删除sys_roles表 角色信息
     * 删除sys_role_menus表 角色菜单信息
     * 删除sys_user_roles表 用户角色信息
     */
    @RequiresPermissions("sys:role:delete")
    @Override
    @Transactional
    public int deleteObject(Integer id) {
        //1.验证数据的合法性
        if (id == null || id <= 0)
            throw new IllegalArgumentException("请先选择");
        //2.基于id删除sys_role_menus表 角色菜单信息
        sysRoleMenuMapper.deleteObjectsByRoleId(id);
        //3.基于id删除sys_user_roles表 用户角色信息
        sysUserRoleMapper.deleteObjectsByRoleId(id);
        //4.删除角色自身
        int rows = sysRoleMapper.deleteObject(id);
        if (rows == 0)
            throw new ServiceException("此记录可能已经不存在");
        //5.返回结果
        return rows;
    }

    /**
     * 基于前端请求,将角色信息以及角色菜单关系信息保存
     */
    @RequiresPermissions("sys:role:add")
    @Override
    @Transactional
    public int saveObject(SysRole entity, Integer[] menuIds) {
        //1.参数有效性校验
        if (entity == null)
            throw new IllegalArgumentException("保存对象不能为空");
        if (StringUtils.isEmpty(entity.getName()))
            throw new IllegalArgumentException("角色名不允许为空");
        if (menuIds == null)
            throw new ServiceException("必须为角色分配权限");

        //2 获取创建用户信息 -- 通过shiro框架SecurityUtils工具类获取
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        //2.1 保存角色自身信息
        entity.setCreatedUser(user.getUsername());
        int rows = sysRoleMapper.insertObject(entity);
        //3.保存角色菜单关系数据
        sysRoleMenuMapper.insertObject(entity.getId(), menuIds);
        //4.返回业务结果
        return rows;
    }

    //基于角色id查询角色信息
    @Override
    public SysRoleMenuVo findObjectById(Integer id) {
        //1.合法性验证
        if (id == null || id <= 0)
            throw new IllegalArgumentException("id的值不合法");
        //2.执行查询
        SysRoleMenuVo result = sysRoleMapper.findObjectById(id);
        //3.验证结果并返回
        if (result == null)
            throw new ServiceException("此记录已经不存在");
        return result;
    }

    @RequiresPermissions("sys:role:update")
    @Override
    @Transactional
    public int updateObject(SysRole entity, Integer[] menuIds) {
        //1.合法性验证
        if (entity == null)
            throw new IllegalArgumentException("更新的对象不能为空");
        if (entity.getId() == null)
            throw new IllegalArgumentException("id的值不能为空");
        if (StringUtils.isEmpty(entity.getName()))
            throw new IllegalArgumentException("角色名不能为空");
        if (menuIds == null || menuIds.length == 0)
            throw new IllegalArgumentException("必须为角色指定一个权限");

        //2.获取修改用户信息 -- 通过shiro框架SecurityUtils工具类获取
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
        entity.setModifiedUser(user.getUsername());
        //2.1更新数据
        int rows = sysRoleMapper.updateObject(entity);
        if (rows == 0)
            throw new ServiceException("对象可能已经不存在");
        //3.更新角色菜单数据--先删除角色菜单数据
        sysRoleMenuMapper.deleteObjectsByRoleId(entity.getId());
        //4.再插入新的角色菜单数据
        sysRoleMenuMapper.insertObject(entity.getId(), menuIds);
        //5.返回数据
        return rows;
    }

    @Override
    public List<CheckBox> findObject() {
        return sysRoleMapper.findObjects();
    }
}
